//
// Created by chen on 2022/1/4.
//

#include "stdio.h"
#include "windows.h"
#include "string.h"

char *concat(char *firstStr, char *lastStr) {
    char *str = (char *) malloc(strlen(firstStr) + strlen(lastStr));
    strcpy(str, firstStr);
    strcat(str, lastStr);
    return str;
    printf("%s\n", str);
}

int main() {
    char *directory = "e:\\clearn\\fchange\\";
//    char *directory = "e:\\test\\a.txt";
    // 打开为目录时，第二个参数，必须要包含 FILE_LIST_DIRECTORY ；第6个参数：必须有 FILE_FLAG_BACKUP_SEMANTICS
    HANDLE hDirectory = CreateFile(directory, // 文件设备名(可以是：文件名、路径名、UNC路径名、逻辑磁盘驱动器、物理磁盘驱动器、COMx[串口]、LPTx[并口]等等)
                                   GENERIC_READ | GENERIC_WRITE|FILE_LIST_DIRECTORY,// 读取方式 当 directory 为目录时， 必须设置 FILE_LIST_DIRECTORY
                                   FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,//共享模式
                                   NULL, //安全属性
                                   OPEN_ALWAYS,// 如何创建
                                   FILE_FLAG_BACKUP_SEMANTICS, // 文件属性 当 directory 是目录时，这里必须是 FILE_FLAG_BACKUP_SEMANTICS
                                   NULL // 用于复制文件句柄
    );
    if (INVALID_HANDLE_VALUE == hDirectory) {
        printf("error: CreateFile\n");
    }

    char notify[1024];
    DWORD BytesReturned = 0;
    memset(notify, 0, sizeof(notify));
    FILE_NOTIFY_INFORMATION *pNotification = (FILE_NOTIFY_INFORMATION *) notify;
    while (1) {
        WINBOOL watch_state = ReadDirectoryChangesW(hDirectory,
                                                    &notify,
                                                    sizeof(notify),
                                                    TRUE,
                                                    FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE,
                                                    (LPDWORD) &BytesReturned, NULL, NULL);
        if (GetLastError() == ERROR_INVALID_FUNCTION) {
            printf("文件监控，系统不支持!");
            break;
        } else if (watch_state == FALSE) {
            printf("watch file fail");
            break;
        } else if (GetLastError() == ERROR_NOTIFY_ENUM_DIR) {
            printf("File monitoring, memory overflow");
            break;
        } else {
            // ReadDirectoryChangesW 数据缓冲区中使用的都是宽字节Unicode，字符串不是 NULL 结尾
            // 将 UTF-16（宽字符）字符串映射到新字符串。新字符串不一定来自多字节字符集
            char AnsiChar[1024] = {0};
            WideCharToMultiByte(CP_ACP, 0,
                                pNotification->FileName,
                                (int) (pNotification->FileNameLength / 2),
                                AnsiChar, 1024, NULL, NULL);
//            char *msg = concat("修改了:", AnsiChar);

//            char AnsiChars[1024] = {0};
//            MultiByteToWideChar(CP_UTF8, 0, msg, strlen(msg) + 1, AnsiChars, 1024);
            switch (pNotification->Action) {
                case FILE_ACTION_ADDED:
                    printf("Created new file: %s\n", AnsiChar);
                    break;
                case FILE_ACTION_MODIFIED:
//                    MessageBoxW(NULL, AnsiChars, L"消息", MB_OK);
                    printf("Modified file: %s\n", AnsiChar);
                    break;
                case FILE_ACTION_RENAMED_NEW_NAME:
                    printf("Rename file: %s\n", AnsiChar);
                    break;
                case FILE_ACTION_RENAMED_OLD_NAME:
                    printf("FILE_ACTION_RENAMED_OLD_NAME file: %s\n", AnsiChar);
                    break;
            }
        }
    }

}